<?php
/**
 * UserRepo.php
 *
 * @copyright   2023 thingsworld.com.cn - All Rights Reserved
 * @link        http://thingsworld.com.cn/
 * @author      stiffer.chen <chenl@thingsworld.com.cn>
 * @created     2023-02-14 01:50:06
 * @modified    2023-02-14 01:50:06
 *
 */

namespace App\Repositories\Customer;

use App\Library\Logger;
use App\Models\CityModel;
use App\Models\Customer;
use App\Models\Customer\User;
use App\Models\Event;
use App\Repositories\CustomerRepo;
use Carbon\Carbon;

class UserRepo
{
    const EDU_HIGH_CODE = 'high'; // 高中
    const EDU_COLLEGE_CODE = 'college'; // 专科
    const EDU_UNDERGRADUATE_CODE = 'undergraduate'; // 本科
    const EDU_MASTER_CODE = 'master'; // 硕士
    const EDU_DOCTOR_CODE = 'doctor'; // 博士

    const EDU_HIGH_TITLE = '高中'; // 高中
    const EDU_COLLEGE_TITLE = '专科'; // 专科
    const EDU_UNDERGRADUATE_TITLE = '本科'; // 本科
    const EDU_MASTER_TITLE = '硕士'; // 硕士
    const EDU_DOCTOR_TITLE = '博士'; // 博士

    const GENDER_MALE_CODE = 'male'; // 男性
    const GENDER_FEMALE_CODE = 'female'; // 女性
    const GENDER_SECRET_CODE = 'secret'; // 保密

    const GENDER_MALE_TITLE = '男性'; // 男性
    const GENDER_FEMALE_TITLE = '女性'; // 女性
    const GENDER_SECRET_TITLE = '保密'; // 保密

    public static function params()
    {
        return [
            'education' => [
                ['code' => self::EDU_HIGH_CODE, 'title' => self::EDU_HIGH_TITLE],
                ['code' => self::EDU_COLLEGE_CODE, 'title' => self::EDU_COLLEGE_TITLE],
                ['code' => self::EDU_UNDERGRADUATE_CODE, 'title' => self::EDU_UNDERGRADUATE_TITLE],
                ['code' => self::EDU_MASTER_CODE, 'title' => self::EDU_MASTER_TITLE],
                ['code' => self::EDU_DOCTOR_CODE, 'title' => self::EDU_DOCTOR_TITLE]
            ],
            'gender' => [
                ['code' => self::GENDER_MALE_CODE, 'title' => self::GENDER_MALE_TITLE],
                ['code' => self::GENDER_FEMALE_CODE, 'title' => self::GENDER_FEMALE_TITLE],
                ['code' => self::GENDER_SECRET_CODE, 'title' => self::GENDER_SECRET_TITLE],
            ]
        ];
    }

    public static function getList()
    {
        $perPage = (int)request('limit');
        if ($perPage < 1) {
            $perPage = 1;
        }

        $builder = User::query()->with('customer');

        $keyword = trim(request()->get('keyword') ?? '');
        $name = trim(request()->get('name') ?? '');
        $gender = trim(request()->get('gender') ?? '');
        $phone = trim(request()->get('phone') ?? '');
        $officePhone = trim(request()->get('office_phone') ?? '');
        $email = trim(request()->get('email') ?? '');
        $duty = trim(request()->get('duty') ?? '');
        $customerId = intval(request()->get('customer_id') ?? '');
        $countryId = intval(request()->get('country_id') ?? '');
        $provinceId = intval(request()->get('province_id') ?? '');
        $cityId = intval(request()->get('city_id') ?? '');
        $countyId = intval(request()->get('county_id') ?? '');
        $customerTag = trim(request()->get('customer_tag') ?? '');
        $customerSource = trim(request()->get('customer_source') ?? '');
        $saveLevel = trim(request()->get('customer_save_level') ?? '');
        $ownerName = trim(request()->get('owner_name') ?? '');
        $createdAt = trim(request()->get('created_at') ?? '');
        $filterCreatedAt = '';
        if ($createdAt) {
            $filterCreatedAt = Carbon::parse($createdAt)->toDateString();
        }

        $status = trim(request()->get('status'));
        if ($status != '') {
            $status = (int)$status;
            if ($status) {
                $queryStatus = 1;
            } else {
                $queryStatus = 0;
            }
        }

        if ($name) {
            $builder->where('name', 'like', "%{$name}%");
        }
        if ($gender) {
            $builder->where('gender', 'like', "%{$gender}%");
        }
        if ($phone) {
            $builder->where('phone', 'like', "%{$phone}%");
        }
        if ($officePhone) {
            $builder->where('office_phone', 'like', "%{$officePhone}%");
        }
        if ($email) {
            $builder->where('email', 'like', "%{$email}%");
        }
        if ($duty) {
            $builder->where('duty', 'like', "%{$duty}%");
        }
        if ($customerId) {
            $builder->where('customer_id', $customerId);
        }
        if ($countryId) {
            $builder->where('country_id', $countryId);
        }
        if ($provinceId) {
            $builder->where('province_id', $provinceId);
        }
        if ($cityId) {
            $builder->where('city_id', $cityId);
        }
        if ($countyId) {
            $builder->where('county_id', $countyId);
        }
        if ($status !== '') {
            $builder->where('status', $queryStatus);
        }

        if ($keyword !== '') {
            $builder->where(function ($query) use ($keyword) {
                $query->where('name', 'like', "%{$keyword}%")
                    ->orWhere('gender', 'like', "%{$keyword}%")
                    ->orWhere('phone', 'like', "%{$keyword}%")
                    ->orWhere('office_phone', 'like', "%{$keyword}%")
                    ->orWhere('email', 'like', "%{$keyword}%")
                    ->orWhere('email', 'like', "%{$keyword}%")
                    ->orWhere('duty', 'like', "%{$keyword}%");
            });
        }

        if ($customerTag !== '' || $customerSource !== '' || $saveLevel !== '' || $ownerName != '') {
            $builder->join('customer', 'customer.id', '=', 'customer_user.customer_id');
            if ($customerTag !== '') {
                $builder->where('customer.tag_name', 'like', "%{$customerTag}%");
            }
            if ($customerSource !== '') {
                $builder->where('customer.source', 'like', "%{$customerSource}%");
            }
            if ($saveLevel !== '') {
                $builder->where('customer.safe_level', 'like', "%{$saveLevel}%");
            }
            if ($ownerName) {
                $builder->where('customer.owner_name', 'like', "%{$ownerName}%");
            }
        }

        if ($filterCreatedAt) {
            $builder->where('customer_user.created_at', '>=', $filterCreatedAt . ' 00:00:00')
                ->where('customer_user.created_at', '<=', $filterCreatedAt . ' 23:59:59');
        }

        $builder->orderByDesc('id');

        return $builder->paginate($perPage);
    }

    public static function store($id)
    {
        $userData = self::getUserData($id);
        $customerId = (int)$userData['customer_id'];
        $isDefault = (int)$userData['is_default'];
        if ($id) {
            $user = Customer\User::find($id);
        } else {
            $user = new Customer\User();
        }
        if (empty($user)) {
            $user = new User();
        }
        $user->fill($userData);
        $user->saveOrFail();
        self::updateDefaultUser($customerId, $user->id, $isDefault);

        $eventId = $userData['event_id'] ?? 0;
        if ($eventId) {
            $event = Event::find($eventId);
            if (!empty($event)) {
                $event->customer_user_id = $user->id;
                $event->saveOrFail();
            }
        }

        return self::one($user->id);
    }

    public static function one($id)
    {
        $user = Customer\User::find($id);
        if (empty($user)) {
            throw new \Exception('用户不存在');
        }
        return $user;
    }

    public static function infoByPhone($phone)
    {
        $phone = trim($phone);

        $customerUser = User::byPhone($phone)->with(['customer'])->first();
        if (empty($customerUser)) {
            throw new \Exception('联系人信息不存在');
        }

        $customerName = $customerUser->customer->name ?? '';
        $customerUserName = $customerUser->name ?? '';
        $address = $customerUser->customer->address ?? '';
        $provinceId = $customerUser->customer->province_id ?? 0;
        $cityId = $customerUser->customer->city_id ?? 0;
        $countyId = $customerUser->customer->county_id ?? 0;
        $province = CityModel::find($provinceId);
        $city = CityModel::find($cityId);
        $county = CityModel::find($countyId);
        return [
            'customer_name' => $customerName,
            'customer_user_name' => $customerUserName,
            'address' => $address,
            'zones' => [
                $province->citycode ?? '',
                $city->citycode ?? '',
                $county->citycode ?? ''
            ],
            'zone_names' => [
                $province->name ?? '',
                $city->name ?? '',
                $county->name ?? ''
            ]
        ];
    }

    public static function destroy($id)
    {
        $user = Customer\User::find($id);
        if (empty($user)) {
            throw new \Exception('用户不存在');
        }
        $user->delete();
    }

    private static function updateDefaultUser(int $customerId, int $customerUserId, int $isDefault)
    {
        $customer = Customer::find($customerId);
        if (empty($customer)) {
            return;
        }
        $defaultUserId = $customer->customer_user_id;
        if (!$defaultUserId) {
            CustomerRepo::setDefaultUser($customerId, $customerUserId);
        }
        if ($defaultUserId && $isDefault) {
            CustomerRepo::setDefaultUser($customerId, $customerUserId);
        }
        if ($defaultUserId && $defaultUserId == $customerUserId && !$isDefault) {
            $customer->customer_user_id = 0;
            $customer->saveOrFail();
        }
    }

    private static function getUserData($id)
    {
        $log = new Logger('user_repo');
        $log->info("store user, ID: {$id}");
        $userData = request()->getContent();
        $userArr = json_decode($userData, true);
        $name = trim($userArr['name'] ?? '');
        if (!$name) {
            throw new \Exception('请输入联系人姓名');
        }
        $gender = trim($userArr['gender'] ?? '');
        $genderCodes = array_keys(collect(self::params()['gender'])->keyBy('code')->toArray());
        if (!in_array($gender, $genderCodes)) {
            $gender = self::GENDER_SECRET_CODE;
        }
        $customerId = $userArr['customer_id'] ?? 0;
        $phone = trim($userArr['phone'] ?? '');

        $phoneUser = User::byPhone($phone)->byCustomerId($customerId)->first();
        $log->info("phone user");
        $log->info($phoneUser);
        if (!$id && !empty($phoneUser)) {
            throw new \Exception('该联系电话已被使用');
        }
        if ($id && !empty($phoneUser) && $phoneUser->id != $id) {
            throw new \Exception('该联系电话已被使用');
        }

        $customer = Customer::find($customerId);
        $customerName = $customer->name ?? '';
        $officePhone = trim($userArr['office_phone'] ?? '');
        $email = trim($userArr['email'] ?? '');

        $birthday = trim($userArr['birthday'] ?? '');
        if ($birthday) {
            $birthday = Carbon::parse($birthday)->toDateString();
        }

        $duty = $userArr['duty'] ?? '';
        $projectRole = $userArr['project_role'] ?? '';

        $countryId = 0;
        $provinceId = $userArr['province_id'] ?? 0;
        $province = CityModel::byCityCode($provinceId)->first();
        if (empty($province)) {
            $province = CityModel::find($provinceId);
        }
        $provinceName = $province->name ?? '';

        $cityId = $userArr['city_id'] ?? 0;
        $city = CityModel::byCityCode($cityId)->first();
        if (empty($city)) {
            $city = CityModel::find($cityId);
        }
        $cityName = $city->name ?? '';

        $countyId = $userArr['county_id'] ?? 0;
        $county = CityModel::byCityCode($countyId)->first();
        if (empty($county)) {
            $county = CityModel::find($countyId);
        }
        $countyName = $county->name ?? '';

        $eventId = $userArr['event_id'] ?? 0;

        $address = trim($userArr['address'] ?? '');
        if (empty($address)) {
            // throw new \Exception('请输入详细地址');
        }

        $status = $userArr['status'] ?? '';
        if ($status != '') {
            $status = (int)$status;
            if ($status) {
                $status = 1;
            } else {
                $status = 0;
            }
        } else {
            $status = 1;
        }

        $result = [
            'name' => $name,
            'gender' => $gender,
            'phone' => $phone,
            'office_phone' => $officePhone,
            'email' => $email,
            'birthday' => $birthday,
            'duty' => $duty,
            'project_role' => $projectRole,
            'customer_id' => $customerId,
            'customer_name' => $customerName,
            'country_id' => $countryId,
            'country_name' => '',
            'province_id' => $provinceId,
            'province_name' => $provinceName,
            'city_id' => $cityId,
            'city_name' => $cityName,
            'county_id' => $countyId,
            'county_name' => $countyName,
            'address' => $address,
            'status' => $status,
            'is_default' => $userArr['is_default'] ?? 0,
            'event_id' => $eventId
        ];
        return $result;
    }

    public static function fetchByAccount($account)
    {
        $user = User::with('customer')->byPhone($account)->first();
        if (empty($user)) {
            $user = User::with('customer')->byEmail($account)->first();
        }
        if (empty($user)) {
            throw new \Exception('账号不存在');
        }
        return $user;
    }
}